package xlcao.sohutv.ui;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import com.appunite.ffmpeg.FFmpegDisplay;
import com.appunite.ffmpeg.FFmpegError;
import com.appunite.ffmpeg.FFmpegListener;
import com.appunite.ffmpeg.FFmpegPlayer;
import com.appunite.ffmpeg.FFmpegStreamInfo;
import com.appunite.ffmpeg.FFmpegSurfaceView;
import com.appunite.ffmpeg.NotPlayingException;

import xlcao.sohutv.R;
import xlcao.sohutv.bean.Const;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.animation.BounceInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MeleTVViewerFragment extends Fragment implements FFmpegListener {
	private String currentURL = "";
	MeleTVServerFragment mServerFragment;
	private FFmpegSurfaceView vp = null;
	private static int screenWidth = 0;
	private static int screenHeight = 0;
	private URLUtil task = null;
	private String mCurrentTVTitle = "";
	private int mVideoStatus = 0;
	private int mCurrentVideoWidth = 0;
	private int mCurrentVideoHeight = 0;
	private int mCurrentRatio = 0;
	private FFmpegPlayer mpegPlayer;

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		// FragmentManager fm = getFragmentManager();
		// Check to see if we have retained the worker fragment.
		// mServerFragment =
		// (MeleTVServerFragment)fm.findFragmentByTag("server");
		// If not retained (or first time running), we need to create it.
		// if (mServerFragment == null) {
		// mServerFragment = new MeleTVServerFragment();
		// fm.beginTransaction().add(mServerFragment, "server").commit();
		// }

		if (savedInstanceState == null) {
			showInitText();
		} else {
			String url = savedInstanceState.getString("videourl");
			if (url == null || "".equals(url)) {
				showInitText();
			} else {
				// updateUrl(url, title);
			}
		}
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		outState.putString("url", currentURL);
		super.onSaveInstanceState(outState);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.support.v4.app.Fragment#onPause()
	 */
	@Override
	public void onPause() {
		Log.d(getTag(), "onPause");
		if (vp != null) {
			if (task != null
					&& (task.getStatus() == AsyncTask.Status.PENDING || task
							.getStatus() == AsyncTask.Status.RUNNING)) {
				task.cancel(true);
			}

			//if (mpegPlayer.isPlaying())
			//	vp.stopPlayback();
		}
		super.onPause();
	}

	boolean isPlayering() {
		if (vp != null) {
		//	return vp.isPlaying();
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see android.support.v4.app.Fragment#onResume()
	 */
	@Override
	public void onResume() {
		// TODO Auto-generated method stub


		super.onResume();
	}

	@SuppressLint("NewApi")
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		Log.d(getTag(), "onCreateView");

		vp = (FFmpegSurfaceView) inflater.inflate(R.layout.videoview, container, true);
		Display display = getActivity().getWindowManager().getDefaultDisplay();
	
		if ( Build.VERSION.SDK_INT>Build.VERSION_CODES.HONEYCOMB) {
			Point pt = new Point();
			display.getSize(pt);
			screenWidth = pt.x;
			screenHeight = pt.y;
		} else {
			screenWidth = display.getWidth();
			screenHeight = display.getHeight();  
		}
	

		vp.setOnTouchListener(new View.OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				hideorShowListView();
				return false;
			}
		});
		this.mpegPlayer = new FFmpegPlayer((FFmpegDisplay) vp, getActivity());
		this.mpegPlayer.setMpegListener(this);

		return vp;
	}

	public void restoreFullScreen() {
		FrameLayout view = (FrameLayout) getActivity().findViewById(
				R.id.viewlayout);
		setVideoScale(Const.SCREEN_FULL);
		mCurrentRatio = Const.SCREEN_FULL;
		view.setPadding(0, 0, 0, 0);
	}
	public void switchFullScreen() {
		FrameLayout view = (FrameLayout) getActivity().findViewById(
				R.id.viewlayout);
		if ( mCurrentRatio == Const.SCREEN_DEFAULT) {
			setVideoScale(Const.SCREEN_FULL);
			mCurrentRatio = Const.SCREEN_FULL;
			view.setPadding(0, 0, 0, 0);
		} else if ( mCurrentRatio == Const.SCREEN_FULL) {
			setVideoScale(Const.SCREEN_DEFAULT);
			mCurrentRatio = Const.SCREEN_DEFAULT;
			view.setPadding((int) (screenWidth * 0.1), 0,
					(int) (screenWidth * 0.1), 0);
		}
	}

	@Override
	public void onDestroyView() {
		Log.d(getTag(), "onDestroyView");
		super.onDestroyView();
	}

	public void updateUrl(String tvUrl, String tvTitle) {

		
		if (! currentURL.equals("")) {
			mpegPlayer.stop();
		}

		if (mVideoStatus == 701) {
			Toast toast = Toast.makeText(getActivity(), getResources()
					.getString(R.string.TOO_QUCICK), Toast.LENGTH_SHORT);
			toast.setGravity(Gravity.BOTTOM, 0, 0);
			toast.show();
			return;
		}	
		setLoadingMsg(tvTitle);
		task = new URLUtil();
		Log.d("playvideo", "begin to connect " + currentURL);
		
		task.execute(tvUrl);
		Log.d("playvideo","onFFStop");
		
		currentURL = tvUrl;
		mCurrentTVTitle = tvTitle;
	
		
		
	}

	private static boolean isWelcomeExist = true;

	private void setLoadingMsg(String msg) {
		if (isWelcomeExist) {
			final LinearLayout welcome = (LinearLayout) getActivity()
					.findViewById(R.id.welcome);
			welcome.setVisibility(View.GONE);
		}
		final LinearLayout loading = (LinearLayout) getActivity().findViewById(
				R.id.fullscreen_loading_indicator);
		TextView tx = (TextView) loading.findViewById(R.id.current_action);
		String msgFormatted = String.format(
				getResources().getString(R.string.LOADING_CONTENT), msg);

		SpannableStringBuilder spannable = new SpannableStringBuilder(
				msgFormatted);
		spannable.setSpan(new ForegroundColorSpan(Color.RED), 4,
				4 + msg.length() + 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
		tx.setText(spannable);
		TranslateAnimation anim = new TranslateAnimation(0, 0, -100, 0);
		anim.setInterpolator(new BounceInterpolator());
		anim.setDuration(1000);
		tx.startAnimation(anim);
		loading.setVisibility(View.VISIBLE);
	}

	@SuppressLint("NewApi")
	public void hideorShowListView() {
		RelativeLayout ll = (RelativeLayout) getActivity().findViewById(
				R.id.listlayout);
		FragmentManager fm = getFragmentManager();
		final MeleTVListFragment tvlistfm = (MeleTVListFragment) fm
				.findFragmentById(R.id.tvlist_fragment);
		if (ll.getVisibility() == View.GONE) {
			ll.setVisibility(View.VISIBLE);
			tvlistfm.loadPos();
			return;
		}
		if (ll.getVisibility() == View.VISIBLE) {
			tvlistfm.savePos();
			ll.setVisibility(View.GONE);
			Toast toast = Toast.makeText(getActivity(), getResources()
					.getString(R.string.CLICK_SCREEN), Toast.LENGTH_SHORT);
			toast.setGravity(Gravity.BOTTOM, 0, 0);
			toast.show();
			return;
		}
		return;

	}

	public void showInitText() {
	}

	public void reload() {
		if (vp != null && currentURL != null) {
			setLoadingMsg(mCurrentTVTitle);
			task = new URLUtil();
			task.execute(currentURL);

		}
	}

	public class URLUtil extends AsyncTask<String, Integer, String> {

		@Override
		protected String doInBackground(String... params) {
			if (params[0].endsWith(".m3u8")
					|| params[0].endsWith(".m3u")) {
				return params[0];
			} else if (params[0].endsWith(".direct")) {
				params[0] = params[0].split(".direct")[0];
				return params[0];
			}
			boolean redir;
			int redirects = 0;
			InputStream in = null;
			String result = "";
			Log.d("playvideo", "asynctask, do inbackground begin");
			// no need to get location
			
			try {
				URL url = new URL(params[0]);
				URLConnection c = url.openConnection();
				c.setConnectTimeout(3000);
				c.setReadTimeout(3000);
				do {
					if (c instanceof HttpURLConnection) {
						((HttpURLConnection) c)
								.setInstanceFollowRedirects(false);
					}
					// We want to open the input stream before getting headers
					// because getHeaderField() et al swallow IOExceptions.
					in = c.getInputStream();
					redir = false;
					if (c instanceof HttpURLConnection) {
						HttpURLConnection http = (HttpURLConnection) c;
						int stat = http.getResponseCode();
						if (stat >= 300 && stat <= 307 && stat != 306
								&& stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
							URL base = http.getURL();
							result = http.getHeaderField("Location");
							URL target = null;
							if (result != null) {
								target = new URL(base, result);
							}
							http.disconnect();
							// Redirection should be allowed only for HTTP and
							// HTTPS
							// and should be limited to 5 redirections at most.
							if (target == null
									|| !("http".equals(target.getProtocol()) || "https"
											.equals(target.getProtocol()))
									|| redirects >= 5) {
								throw new SecurityException(
										"illegal URL redirect");
							}
							redir = true;
							c = target.openConnection();
							redirects++;
						}
					}
				} while (redir && task != null && !task.isCancelled());
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
				if (task != null)
					task.cancel(true);
			}
			return result;
		}

		@Override
		protected void onCancelled() {
			/*
			 * final LinearLayout loading = (LinearLayout)
			 * getActivity().findViewById( R.id.fullscreen_loading_indicator);
			 * if (loading.getVisibility() == View.VISIBLE) {
			 * loading.setVisibility(View.GONE); }
			 */
			// mVideoStatus = 0;

			Log.d("playvideo", "onCancelled");
		}

		@Override
		protected void onPostExecute(String result) {

			if (vp == null || result == null || "".equals(result.trim())) {
				LinearLayout loading = (LinearLayout) getActivity()
						.findViewById(R.id.fullscreen_loading_indicator);
				loading.setVisibility(View.GONE);
				UserDialogFragment newFragment = UserDialogFragment
						.newInstance(Const.DIALOG_ERROR_RETRY);
				newFragment.show(getFragmentManager(), "DIALOG");
				mVideoStatus = 0;
				return;
			}

			// setVideoScale(Const.SCREEN_DEFAULT);
			//vp.setVideoURI(Uri.parse(result));
		//	mpegPlayer.setMpegListener(this);
			mpegPlayer.setDataSource(result);
			setVideoScale(Const.SCREEN_FULL);
			mCurrentRatio = Const.SCREEN_FULL;
		//	mpegPlayer.stop();
		}

		@Override
		protected void onPreExecute() {
			Log.d("playvideo", "asynctask, onPreExecute begin");

		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			Log.d("playvideo", "asynctask, onProgressUpdate begin");
			// update status
			// progressDialog.setProgress(values[0].intValue());
			// Log.d(getTag(), "Progress is " + values[0].intValue());
		}
	}

	public void setVideoScale(int flag) {

		if (vp == null)
			return;

		switch (flag) {
		case Const.SCREEN_FULL:
			vp.setVideoScale(screenWidth, screenHeight);
			break;

		case Const.SCREEN_DEFAULT:
			vp.setVideoScale((int) (screenWidth * 0.8), screenHeight);
			break;
		default:
			break;
		}
	}
	void moveToCenter() {
		FrameLayout view = (FrameLayout) getActivity().findViewById(
				R.id.viewlayout);
		if ( mCurrentRatio == Const.SCREEN_FULL) {
			setVideoScale(Const.SCREEN_FULL);
			view.setPadding(0, 0, 0, 0);
		} else if ( mCurrentRatio == Const.SCREEN_DEFAULT) {
			setVideoScale(Const.SCREEN_DEFAULT);
			view.setPadding((int) (screenWidth * 0.1), 0,
					(int) (screenWidth * 0.1), 0);
		}
	}

	@Override
	public void onFFDataSourceLoaded(FFmpegError err, FFmpegStreamInfo[] streams) {
		LinearLayout loading = (LinearLayout) getActivity()
		.findViewById(R.id.fullscreen_loading_indicator);
		loading.setVisibility(View.GONE);
		
		if (err != null) {
	
			UserDialogFragment newFragment = UserDialogFragment
					.newInstance(Const.DIALOG_ERROR_RETRY);
			newFragment.show(getFragmentManager(), "DIALOG");
			mVideoStatus = 0;
		} else {
			mpegPlayer.resume();
			MeleTVListFragment list = (MeleTVListFragment) getFragmentManager().findFragmentById(R.id.tvlist_fragment);
			list.delayedHide(5000);
		}
		
	}

	@Override
	public void onFFResume(NotPlayingException result) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onFFPause(NotPlayingException err) {
		// TODO Auto-generated method stub
		Log.d("playvideo","onFFPause");
		
	}

	@Override
	public void onFFStop() {
	
	}

	@Override
	public void onFFUpdateTime(int currentTimeS, int videoDurationS,
			boolean isFinished) {
		// TODO Auto-generated method stub
		Log.d("playvideo","onFFUpdateTime");
	}

	@Override
	public void onFFSeeked(NotPlayingException result) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		this.mpegPlayer.setMpegListener(null);
		this.mpegPlayer.stop();
	}

	@Override
	public void onFFError() {
		// TODO Auto-generated method stub
		UserDialogFragment newFragment = UserDialogFragment
		.newInstance(Const.DIALOG_ERROR_RETRY);
		newFragment.show(getFragmentManager(), "DIALOG");
		mVideoStatus = 0;
	}
}